<script>
	// 在js中,绝对不存在对象嵌套对象的情况出现,实际上,每个对象都是兄弟关系
	/*
  闭包相关
  1.闭包的产生条件
    -必须具有函数嵌套关系
    -内部函数使用外部函数的变量

    问题:如果内部函数没有被外部函数返回出去,是否存在闭包?
    答案:存在

    闭包分为两种
        -有效闭包   ->  内部函数呗外部函数返回出去,最终该闭包会一直存在,可以供后续代码使用
        -无效闭包   ->  内部函数没有被外部函数返回出去,导致这个闭包存在时间非常短暂,但是它存在过

  2.闭包的产生时机
    外部函数必须被调用(因为如果不调用该函数,内部代码不会被解析)
    内部函数执行函数定义的时候

  3.闭包的优点
    延长局部变量的生命周期
        由于内部函数没有被销毁,该函数还是用到外层的变量,如果外层的变量被销毁,代码将无法执行
    实现js模块化
        可以在外层函数中定义数据,并定义操作该数据的方法,最终将操作数据的方法暴露给外层作用域,用于操作数据
            此方法可以保证该数据的安全性,无法实现对内部数据的其余的未定义操作

  4.闭包的缺点
    内存泄漏和内存溢出
    可能出现的情况:内存泄漏
    导致的严重结果:内存溢出

    本来应该被释放掉的内存空间,由于闭包的原因,导致内存空间无法正常释放

  5.如何解决闭包的副作用
    将使用闭包的函数的引用全部释放掉
        流程:由于内部函数没有被销毁,所以内部函数使用的闭包也不会被销毁
        只要内部函数没有人使用,那么内部函数就会被销毁,内部函数被销毁最终导致闭包被销毁

    减少使用闭包

  6.闭包的使用场景
    1.vue原理保存dep
    2.封装请求函数
    3.函数节流,函数防抖
    4.函数柯里化

    一定要提前准备好场景

  7.闭包是什么?
    闭包是一个js对象,它内部存储这内部函数所使用到的变量名和数值
    闭包其实就是意外存活的变量对象
        变量对象本应跟随外层函数的执行上下文一起销毁,但是他被内部函数的Scopes数组引用,导致垃圾回收机制无法销毁

  执行上下文:
    执行上下文就是每次调用某个函数时,都会自动开辟的一块全新的内存空间
    执行上下文分为两部分:
        -执行当前函数所需要的内存空间
        -变量对象(用于收集作用域中所有的变量以及变量值)
            变量对象其实就是作用域规则的执行结果

    1.创建时机
        在函数调用的时候,会自动创建
    2.销毁时机
        函数执行结束的时候,会自动出栈,被垃圾回收机制销毁
        注意:由于每次函数执行结束的时候,执行上下文会被销毁,所以每次执行的时候都会重新生成全新的执行上下文
            执行上下文被销毁->变量对象被销毁->存储的所有变量都会被销毁

  垃圾回收机制
    js引擎会将没有人(标识或者属性)引用的对象进行释放
    基础数据类型的数据,只会被覆盖或者被顺带删除
    对象由于可能被多个标识或者属性引用,需要通过垃圾回收机制进行判断,是否应该要被回收

    早期:引用计数法
        缺点:很可能出现两个都应该被回收的对象,互相引用对方的情况,导致双方的计数器count都不会变为0,都不会被回收

    目前:Scavenge机制
    js引擎会从window身上开始,逐层遍历所有属性,将遇到的新对象存入新生代区,将遇到的多次出现的旧对象存入老生代区
    该机制分为2种区域(数组)
      新生代区
          新创建的对象(很可能马上就要销毁的对象)都会被放置于新生代区中
          新生代区中分为from和to两个数组,分别用于收集之前存在的所有对象,和当前存在的所有对象


          如何判断一个对象应该放在新生代区还是老生代区
              如果一个对象多次出现在to数组中,就说明该对象可以存活的比较久,这类对象就会被放入老生代区

          性能:通过空间换取时间

      老生代区
          可能存活比较久的对象都会被放置于老生代区中
          流程:
              1.在逐层遍历所有属性,将正在被使用的对象打上标记
              2.当所有属性遍历结束,开始遍历老生代区数组,将内部无用的对象(没有标记的对象)全部删除
              3.整合内存,将所有的对象紧凑存放,节省内存空间
          性能:通过时间换取空间

*/
</script>
